package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.HotArticleService;
import com.heima.common.constants.ArticleConstants;
import com.heima.common.redis.CacheService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.vos.ArticleVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Du leilei
 * @version 1.0
 * @Description
 * @createTime 2023年09月22日 14:52:00
 */
@Service
public class HotArticleServiceImpl implements HotArticleService {
    @Autowired
    private ApArticleMapper apArticleMapper;

    @Autowired
    private CacheService cacheService;
    /**
     * 计算热点文章
     */
    @Override
    public void hotArticle() {
        long fiveDay = System.currentTimeMillis() - (1000L * 60 * 60 * 24 * 5);
        LambdaQueryWrapper<ApArticle> wrapper = Wrappers.<ApArticle>lambdaQuery().ge(ApArticle::getPublishTime, new Date(fiveDay));
        List<ApArticle> list = apArticleMapper.selectList(wrapper);

        List<ArticleVO> articleVOS = computeScore(list);

        //3. 将分值排名前30的文章作为热点文章存入redis
        //3.1 先排出各个频道里的30篇热门文章
        //a. 拿到所有频道
        List<Integer> channelIds = list.stream().map(ApArticle::getChannelId).distinct().collect(Collectors.toList());
        //b.遍历各个频道
        for (Integer channelId : channelIds) {
            //对该频道内的文章进行分数排名
            List<ArticleVO> voList = articleVOS.stream().filter(articleVO -> articleVO.getChannelId().equals(channelId)).collect(Collectors.toList());
            sortAndSetCache(channelId+"",voList);
        }
        //3.2 再排出推荐频道里的30篇文章
        sortAndSetCache("__all__",articleVOS);
    }

    //对文章进行分数排序并存入redis缓存
    private void sortAndSetCache(String channelId, List<ArticleVO> voList) {
        //按分数降序
        Collections.sort(voList, new Comparator<ArticleVO>() {
            @Override
            public int compare(ArticleVO o1, ArticleVO o2) {
                return o2.getScore() - o1.getScore();
            }
        });
        //截取出集合中前30篇进行热点文章的缓存
        if (voList.size() > 30){
            voList = voList.stream().limit(30).collect(Collectors.toList());
        }
        cacheService.set(ArticleConstants.HOT_ARTICLE+ channelId, JSON.toJSONString(voList));
    }

    private List<ArticleVO> computeScore(List<ApArticle> list) {

        if (list != null && list.size()>0){
            List<ArticleVO> articleVOS = list.stream().map(apArticle -> {
                int score = 0;

                if (apArticle.getViews() != null) {
                    score += apArticle.getViews();
                }
                if (apArticle.getLikes() != null) {
                    score += (apArticle.getLikes() * 3);
                }
                if (apArticle.getComment() != null) {
                    score += (apArticle.getComment() * 5);
                }
                if (apArticle.getCollection() != null) {
                    score += (apArticle.getCollection() * 8);
                }
                ArticleVO articleVO = new ArticleVO();
                BeanUtils.copyProperties(apArticle, articleVO);
                articleVO.setScore(score);
                return articleVO;
            }).collect(Collectors.toList());
            return articleVOS;
        }
        else {return null; }
    }
}
